home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / getlines.zip / GETLINES.C < prev    next >
C/C++ Source or Header  |  1994-05-21  |  5KB  |  190 lines

  1. /* GETLINES:        -- TEXT FILE UTILITY --
  2.  *
  3.  *  Given a list of line numbers within a specifed text file
  4.  *  display the corresponding lines.
  5.  *
  6.  *  Note that sorted input lists process much faster!
  7.  *  Previously scanned lines require program to rewind
  8.  *  the file stream and recount the line numbers.
  9.  *
  10.  *  This program will compile with Turbo/Borland C++, UNIX ANSI C,
  11.  *  GNU C, and VAX/VMS C.
  12.  *
  13.  *  Developed by Jason Mathews
  14.  *    NASA/Goddard Space Flight Center
  15.  *    <mathews@nssdca.gsfc.nasa.gov>
  16.  *
  17.  *  Copyright (C) 1994 by Jason Mathews.  Permission is granted to any
  18.  *  individual or institution to use, copy or modify this software so long
  19.  *  as it is not sold for profit, provided this copyright notice is retained.
  20.  *
  21.  *  Modification history:
  22.  *
  23.  *    20-May-94  Original version.
  24.  *
  25.  *****************************************************************************/
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29.  
  30. #if defined __MSDOS__
  31. #  include <io.h>
  32. #elif defined unix
  33. #  include <unistd.h>
  34. #  define ALT_SW
  35. #elif defined vms
  36. #  include <unixio.h>
  37. #endif /* ?__MSDOS__ */
  38.  
  39. /* define alternate switch for non-unix systems */
  40. #ifndef unix
  41. #  define ALT_SW *argv[i]=='/' ||
  42. #endif
  43.  
  44. int  interactive;    /* flag indicating interactive mode */
  45. int  errcode    = 0; /* return error code */
  46. char bShowLines = 0; /* boolean flag to show line numbers */
  47. char buf[512];
  48. char copyright[] = "GETLINES v1.0 (C) 1994 Jason Mathews\n";
  49.  
  50. void usage(void)
  51. {
  52.     fprintf(stderr, copyright);
  53.     fprintf(stderr, "Show specified lines of text file given line number(s)\n\n");
  54.     fprintf(stderr, "Usage: GETLINES [filename] [-ln] [-cn] [-n]\n\n");
  55.     fprintf(stderr, "  filename = File to search\n");
  56.     fprintf(stderr, "  -ln      = Display line number n, where n >= 1\n");
  57.     fprintf(stderr, "  -cn      = Display n lines (default=1)\n");
  58.     fprintf(stderr, "  -n       = Prefix line with line numbers\n\n");
  59.     fprintf(stderr, "Default input accepted from stdin.\n\n");
  60.     fprintf(stderr, "Examples: > GETLINES foo.dat.c -n < lines.dat\n");
  61.     fprintf(stderr, "          > GETLINES bar.c -l100 -c10\n");
  62.     exit(1);
  63. }
  64.  
  65. /*
  66.  * Purpose:    Search text file for specified line number
  67.  *
  68.  * Returns:    0 if successful, otherwise 1 if error
  69.  */
  70. int getline( FILE* fp, int target_line )
  71. {
  72.   static int linenum = 0;
  73.    /* if input line out of order then rewind file */
  74.     if (target_line < linenum)
  75.     {
  76.         rewind(fp);
  77.         linenum = 0;
  78.     }
  79.     while (linenum < target_line)
  80.     {
  81.         if (fgets(buf, sizeof(buf), fp)==0)
  82.         {
  83.             fprintf(stderr, "%s: Invalid line %d: file has only %d lines\n",
  84.                     (interactive ? "Warning" : "Error"), target_line, linenum);
  85.         if (interactive)
  86.         {
  87.         rewind(fp);
  88.         linenum = 0;
  89.         }
  90.             return !interactive;
  91.         }
  92.         linenum++;
  93.     }
  94.  
  95.     if (bShowLines) printf("%-7d", linenum);
  96.     printf("%s", buf);
  97.     return 0;
  98. }
  99.  
  100. /*
  101.  *  Scan text file using line numbers read from stdin.
  102.  */
  103. void scan( FILE* fp )
  104. {
  105.  int target_line;
  106.  char* status = interactive ? "Warning" : "Error";
  107.  char linestr[80];
  108.  
  109.  do {
  110.      if (interactive)
  111.      {
  112.   moreInput:
  113.     fprintf(stderr, "Line number to extract: ");
  114.      }
  115.      if (!gets(linestr)) break; /* eof? */
  116.      if ((target_line = atoi(linestr)) < 1)
  117.      {
  118.     fprintf(stderr, "%s: Illegal line number %s\n", status, linestr);
  119.     if (interactive) goto moreInput;
  120.     errcode = 1; /* error */
  121.     break;
  122.      }
  123. #ifdef vms
  124.      if (interactive) fprintf(stderr, "\n");
  125. #endif
  126.  } while (!getline(fp, target_line));
  127. }
  128.  
  129. int main( int argc, char**argv )
  130. {
  131.   FILE* fp;
  132.   char *filename = NULL;
  133.   int i;
  134.   int linenum = 0;
  135.   int count   = 1;
  136.  
  137.   for (i=1; i < argc; i++)
  138.   {
  139.     if (ALT_SW *argv[i] == '-')
  140.     {
  141.     switch (argv[i][1]) {
  142.         case 'n':
  143.         bShowLines = 1;
  144.         break;
  145.             case 'l':
  146.         if ((linenum = atoi(argv[i]+2)) < 1) goto Arg_Error;
  147.         break;
  148.             case 'c':
  149.         if ((count = atoi(argv[i]+2)) < 1) goto Arg_Error;
  150.         if (!linenum) linenum = 1;
  151.         break;
  152.         default:
  153.         Arg_Error:
  154.         fprintf(stderr, "Error: Illegal parameter or value %s\n\n", argv[i]);
  155.         case 'h':
  156.         case '?':
  157.         usage();
  158.     }
  159.     }
  160.     else filename = argv[i];
  161.   } /* for each arg */
  162.  
  163.   /* interactive mode if input is from keyboard, otherwise piped input */
  164.   interactive = isatty(fileno(stdin));
  165.  
  166.   if (!filename)
  167.   {
  168.     if (interactive) fprintf(stderr, "Filename to search: ");
  169.     gets(filename = buf);
  170.   }
  171.  
  172.   fp = fopen(filename, "r");
  173.   if (!fp)
  174.   {
  175.     fprintf(stderr, "Error: Cannot open ");
  176.     perror(filename);
  177.     usage();
  178.   }
  179.  
  180.   if (linenum != 0)
  181.   {
  182.     interactive = 0; /* disable interative mode */
  183.     while (count && !getline(fp, linenum++)) count--;
  184.   }
  185.   else scan(fp);
  186.  
  187.   fclose(fp);
  188.   return errcode;
  189. }
  190.